package com.sky.service.admin.impl;

import com.sky.dto.GoodsSalesDTO;
import com.sky.mapper.admin.ReportMapper;
import com.sky.service.admin.ReportService;
import com.sky.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ReportServiceImpl implements ReportService {
    @Autowired
    private ReportMapper reportMapper;

    /**
     * 统计营业额
     * @param begin
     * @param end
     * @return
     */
    @Override
    public TurnoverReportVO amountCollect(LocalDate begin, LocalDate end) {
        ArrayList<LocalDate> allDays = getAllDays(begin, end);
        TurnoverReportVO turnoverReportVO = new TurnoverReportVO();
        turnoverReportVO.setDateList(StringUtils.collectionToCommaDelimitedString(allDays));
        //调用mapper获取到营业额数据
        List<OrderAmountByDaysVO> amountByDaysVOS =  reportMapper.amountCollect(begin,end.plusDays(1L));
        log.info("{}",amountByDaysVOS);
        //准备一个接收金额的集合,如果amountByDaysVOS中有值,则使用,没有值则为0
        List<BigDecimal> amounts = new ArrayList<>();
        allDays.forEach(date ->{
            OrderAmountByDaysVO orderAmountByDaysVO = amountByDaysVOS.stream().filter(amountByDaysVO -> amountByDaysVO.getOrderTime().equals(date)).findFirst().orElse(new OrderAmountByDaysVO(date,new BigDecimal(0),0,0));
            amounts.add(orderAmountByDaysVO.getAmount());
        });
        turnoverReportVO.setTurnoverList(StringUtils.collectionToCommaDelimitedString(amounts));
        return turnoverReportVO;
    }

    @Override
    public OrderReportVO orderCollect(LocalDate begin, LocalDate end) {
        ArrayList<LocalDate> allDays = getAllDays(begin, end);
        List<OrderAmountByDaysVO> amountByDaysVOS = reportMapper.orderCollect(begin, end.plusDays(1L));
        ArrayList<Integer> totalCount = new ArrayList<>();
        ArrayList<Integer> completeCount = new ArrayList<>();
        allDays.forEach(oneday -> {
            OrderAmountByDaysVO orderAmountByDaysVO = amountByDaysVOS.stream().filter(e -> e.getOrderTime().equals(oneday)).findFirst().orElse(new OrderAmountByDaysVO(oneday, new BigDecimal(0), 0, 0));
            totalCount.add(orderAmountByDaysVO.getTotalCount());
            completeCount.add(orderAmountByDaysVO.getCompleteCount());
        });
        Integer completeNum = completeCount.stream().reduce(Integer::sum).get();
        Integer totalNum = totalCount.stream().reduce(Integer::sum).get();
        Double completeRate = (double)completeNum/totalNum;
        OrderReportVO vo = OrderReportVO.builder().dateList(StringUtils.collectionToCommaDelimitedString(allDays))
                .orderCountList(StringUtils.collectionToCommaDelimitedString(totalCount))
                .validOrderCountList(StringUtils.collectionToCommaDelimitedString(completeCount))
                .totalOrderCount(totalNum)
                .validOrderCount(completeNum)
                .orderCompletionRate(completeRate)
                .build();
        return vo;

    }

    /**
     * 销量前10
     * @param begin
     * @param end
     * @return
     */
    @Override
    public SalesTop10ReportVO top10(LocalDate begin, LocalDate end) {
        List<GoodsSalesDTO> goodsSalesDTOS = reportMapper.GoodsTop10(begin, end.plusDays(1L));
        List<String> nameList = goodsSalesDTOS.stream().map(GoodsSalesDTO::getName).toList();
        List<Integer> numList = goodsSalesDTOS.stream().map(GoodsSalesDTO::getNumber).toList();
        SalesTop10ReportVO reportVo = SalesTop10ReportVO.builder().nameList(StringUtils.collectionToCommaDelimitedString(nameList))
                .numberList(StringUtils.collectionToCommaDelimitedString(numList)).build();
        return reportVo;
    }

    @Override
    public UserReportVO userStatistics(LocalDate begin, LocalDate end) {
        List<UserCollectVO> userCollectVOS = reportMapper.userStatistics(begin, end);
        List<LocalDate> dates = userCollectVOS.stream().map(UserCollectVO::getDate).toList();
        List<Integer> newUsers = userCollectVOS.stream().map(UserCollectVO::getNewUser).toList();
        List<Integer> totalUsers = userCollectVOS.stream().map(UserCollectVO::getTotalUser).toList();
        UserReportVO reportVO = UserReportVO.builder().newUserList(StringUtils.collectionToCommaDelimitedString(newUsers))
                .dateList(StringUtils.collectionToCommaDelimitedString(dates))
                .totalUserList(StringUtils.collectionToCommaDelimitedString(totalUsers))
                .build();
        return reportVO;
    }

    private static ArrayList<LocalDate> getAllDays(LocalDate begin, LocalDate end) {
        //获取从开始到结束日期的每一天的日期集
        ArrayList<LocalDate> dateList = new ArrayList<>();
        dateList.add(begin);
        while(!begin.equals(end)){
            begin = begin.plusDays(1L);
            dateList.add(begin);
        }
        return dateList;
    }


}
